package com.zhanghp.class01;

import com.zhanghp.class01.sort.InsertionSort;
import com.zhanghp.class01.sort.utils.SortUtils;
import com.zhanghp.utils.CommonUtils;

import java.util.Arrays;

/**
 * @author zhanghp
 * @date 2023/8/12 9:50
 */
public class Code08_Calipers {
    public static void main(String[] args) {
        // 数组拷贝并打印
        int[] arr = lenRandomValueRandom(10, 10);
        int[] arr2 = copyArr(arr);
        SortUtils.printArrs(arr, arr2);
        System.out.printf("%s%n", isEqual(arr, arr2));
        CommonUtils.printDivingLine();
        // 有序函数验证
        InsertionSort.forwardInsertSortOptimize(arr);
        Arrays.sort(arr2);
        SortUtils.printArr(arr);
        SortUtils.printArr(arr2);
        System.out.printf("%s%n", isEqual(arr, arr2));
        isSorted(arr);
        isSorted(arr2);
        CommonUtils.printDivingLine();
        // 二进制移位 - isSorted（）
        caliperIsSorted();
        CommonUtils.printDivingLine();
        caliperSortArr();

    }

    /**
     * 随机生成数组
     * <ul>
     *     <li>length: maxLen</li>
     *     <li>value: [0, maxValue)</li>
     * </ul>
     *
     * @param maxLen   最大长度
     * @param maxValue 最大值
     * @return 随机数组
     */
    public static int[] lenRandomValueRandom(int maxLen, int maxValue) {
        if (maxLen < 0) {
            throw new IllegalArgumentException("数组长度不能为负数");
        }
        int randLength;
        do {
            randLength =((int) (Math.random() * maxLen));
        } while (randLength < 2);

        // 随机长度
        int[] randArr = new int[randLength];
        // 随机数值
        for (int i = 0; i < randArr.length; i++) {
            randArr[i] = ((int) (Math.random() * maxValue));
        }
        return randArr;
    }

    /**
     * 复制数组并返回
     *
     * @param arr 需要复制的数组
     * @return 复制的数组
     */
    public static int[] copyArr(int[] arr){
        if (arr.length == 0) {
            return new int[0];
        }
        int[] copyArr = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            copyArr[i] = arr[i];
        }
        return copyArr;
    }

    /**
     * 2个数组是否相等
     *
     * @param arr1 数组1
     * @param arr2 属组
     * @return  <ul></li><li>true: 相等</li><li>false：不等</li></ul>
     */
    public static boolean isEqual(int[] arr1, int[] arr2){
        if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
            return false;
        }
        if (arr1 == null && arr2 == null) {
            return true;
        }
        if (arr1.length != arr2.length || arr1.length == 0) {
            return false;
        }
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 数组是否为有序：小 -> 大
     *
     * @param arr 数组
     * @return <ul></li><li>true: 有序</li><li>false：无序</li></ul>
     */
    public static boolean isSorted(int[] arr){
        if(arr.length < 2){
            return true;
        }
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            // 低位比高位大，则返回false
            if (max > arr[i]) {
                return false;
            }
            max = arr[i];
        }
        return true;
    }

    /**
     * 对数器 - 验证isSorted()
     */
    public static void caliperIsSorted(){
        int maxLen = 100;
        int maxValue = 20;
        for (int i = 0; i < CommonUtils.TEST_COUNT; i++) {
            int[] arr = lenRandomValueRandom(maxLen, maxValue);
            Arrays.sort(arr);
            if (!isSorted(arr)) {
                SortUtils.printArrs(arr);
                System.out.printf("%s%n", "Fucked!");
            }
        }
    }

    /**
     * 对数器 - 插入排序验证
     */
    public static void caliperSortArr(){
        int maxLen = 100;
        int maxValue = 20;
        for (int i = 0; i < CommonUtils.TEST_COUNT; i++) {
            int[] arr = lenRandomValueRandom(maxLen, maxValue);
            int[] copyArr = copyArr(arr);
            InsertionSort.reverseInsertSortOptimize(arr);
            if (!isSorted(arr)) {
                System.out.printf("%s%n", "Fucking fucked");
                SortUtils.printArrs(arr, copyArr);
                break;
            }
        }
    }
}
